#include "snapshot.h"

extern CPU_state cpu;

int store_snapshot(const char* filename) {
	// Need to optimize !!!!!
#ifdef CONFIG_ISA_riscv64
	size_t write_size;
	FILE* fd = fopen(filename, "wb");
	if (fd == NULL) {
		printf("Can't open file: %s.\n", filename);
		return -1;
	}
	for (int i = 0; i < 32; ++i) {
		write_size = fwrite(&cpu.gpr[i], REG_WIDTH, 1, fd);
		assert(write_size != 0);
	}

	write_size = fwrite(&cpu.pc, REG_WIDTH, 1, fd);
	assert(write_size != 0);

	// write_size = fwrite(&cpu.mstatus.value, REG_WIDTH, 1, fd);
	// assert(write_size != 0);

	// write_size = fwrite(&cpu.mtvec, REG_WIDTH, 1, fd);
	// assert(write_size != 0);

	// write_size = fwrite(&cpu.mepc, REG_WIDTH, 1, fd);
	// assert(write_size != 0);

	// write_size = fwrite(&cpu.mcause, REG_WIDTH, 1, fd);
	assert(write_size != 0);

	size_t nmemb = CONFIG_MSIZE / MAX_BUF_SIZE;
	write_size = fwrite(guest_to_host(RESET_VECTOR), MAX_BUF_SIZE, nmemb, fd);
	assert(write_size != 0);


	fclose(fd);
#endif
	return 0;
}

int load_snapshot(const char* filename) {
	// Need to optimize !!!!!
#ifdef CONFIG_ISA_riscv64
	size_t read_size;
	FILE* fd = fopen(filename, "rb");
	if (fd == NULL) {
		printf("Can't open file: %s.\n", filename);
		return -1;
	}

	for (int i = 0; i < 32; ++i) {
		read_size = fread(&cpu.gpr[i], REG_WIDTH, 1, fd);
		assert(read_size != 0);
	}

	read_size = fread(&cpu.pc, REG_WIDTH, 1, fd);
	assert(read_size != 0);

	// read_size = fread(&cpu.mstatus.value, REG_WIDTH, 1, fd);
	// assert(read_size != 0);

	// read_size = fread(&cpu.mtvec, REG_WIDTH, 1, fd);
	// assert(read_size != 0);

	// read_size = fread(&cpu.mepc, REG_WIDTH, 1, fd);
	// assert(read_size != 0);

	// read_size = fread(&cpu.mcause, REG_WIDTH, 1, fd);
	// assert(read_size != 0);

	size_t nmemb = CONFIG_MSIZE / MAX_BUF_SIZE;
	read_size = fread(guest_to_host(RESET_VECTOR), MAX_BUF_SIZE, nmemb, fd);
	assert(read_size != 0);

	fclose(fd);
#endif
	return 0;
}